﻿using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.JsonPatch;
using yt_.netcore3._1_webapi_les_jackson.Data;
using yt_.netcore3._1_webapi_les_jackson.Dtos;
using yt_.netcore3._1_webapi_les_jackson.Models;

namespace yt_.netcore3._1_webapi_les_jackson.Controllers
{
    //api/commands
    [Route("api/[controller]")]
    [ApiController]
    public class CommandsController : ControllerBase
    {
        private readonly ICommanderRepo _commanderRepo;
        private readonly IMapper _mapper;

        public CommandsController(ICommanderRepo commanderRepo,IMapper mapper)
        {
            _commanderRepo = commanderRepo;
            _mapper = mapper;
        }
        //GET api/commands
        [HttpGet]
        public ActionResult<IEnumerable<CommandReadDto>> GetAllCommands()
        {
            var commands = _commanderRepo.GetAllCommands();

            return Ok(_mapper.Map<IEnumerable<CommandReadDto>>(commands));
        }
        //GET api/commands/{id}
        [HttpGet("{id}",Name = "GetCommandById")]
        public async Task<ActionResult<CommandReadDto>> GetCommandById(int id)
        {
            var command = await _commanderRepo.GetCommandById(id);
            if (command == null)
            {
                return NotFound();
            }
            var commandDto = _mapper.Map<CommandReadDto>(command);
            return Ok(commandDto);
        }

        //POST api/commands
        [HttpPost]
        public async Task<ActionResult<CommandReadDto>> CreateCommand(CommandCreateDto commandCreateDto)
        {
            var commandModel = _mapper.Map<Command>(commandCreateDto);

            await _commanderRepo.CreateCommand(commandModel);

            _commanderRepo.SaveChanges();

            var commandReadDto = _mapper.Map<CommandReadDto>(commandModel);


            return CreatedAtRoute(nameof(GetCommandById),new {Id = commandReadDto.Id},commandReadDto);
        }

        [HttpPut("{id}")]
        public async Task<ActionResult<CommandReadDto>> UpdateCommand(int id, CommandUpdateDto commandUpdateDto)
        {
            var commandModelFromRepo = await _commanderRepo.GetCommandById(id);
            if (commandModelFromRepo == null)
            {
                return NotFound();
            }

            _mapper.Map(commandUpdateDto,commandModelFromRepo);

            _commanderRepo.UpdateCommand(commandModelFromRepo);

            _commanderRepo.SaveChanges();

            //var commandReadDto = _mapper.Map<CommandReadDto>(commandModelFromRepo);

            return NoContent();

        }

        //PATCH api/commands/{id}
        [HttpPatch("{id}")]
        public async Task<ActionResult> PartialCommandUpdate(int id, JsonPatchDocument<CommandUpdateDto> patchDocument)
        {
            var commandModelFromRepo = await _commanderRepo.GetCommandById(id);
            if (commandModelFromRepo == null)
            {
                return NotFound();
            }

            var commandToPatch = _mapper.Map<CommandUpdateDto>(commandModelFromRepo);

            patchDocument.ApplyTo(commandToPatch,ModelState);

            if (!TryValidateModel(commandToPatch))
            {
                return ValidationProblem(ModelState);
            }

            _mapper.Map(commandToPatch, commandModelFromRepo);

            _commanderRepo.UpdateCommand(commandModelFromRepo);

            _commanderRepo.SaveChanges();

            return NoContent();
        }

        //DELETE api/commands/{id}
        [HttpDelete("{id}")]
        public async Task<ActionResult> DeleteCommand(int id)
        {
            var command = await _commanderRepo.GetCommandById(id);
            if (command == null)
            {
                return NotFound();
            }

            _commanderRepo.DeleteCommand(command);

            _commanderRepo.SaveChanges();

            return NoContent();
        }
    }
}
